import base64
import binascii

from flask import current_app, make_response, request
from flask_restx import Resource, reqparse
from sqlalchemy import and_

from app.common.libs import verify_password
from app.models.roleModel import Role, UserRole
from configs.settings import flask_config
from tools import redis_conn as redis_store
from utils.captcha import captcha

from .urls import imageBlueprint


class Login(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument("username", help="登录账户不能为空", required=True)
        parser.add_argument("password", help="账户密码不能为空", required=True)
        parser.add_argument("image_code", help="验证码不能为空", required=True)
        parser.add_argument("image_code_id", help="验证码id不能为空", required=True)
        args = parser.parse_args()

        try:
            real_image_code = redis_store.get("ImageCode_" + args["image_code_id"])
            if real_image_code:
                redis_store.delete("ImageCode_" + args["image_code_id"])
        except Exception as e:
            current_app.logger.error(e)
            return {"code": 401, "data": "获取图片验证码失败"}

        if not real_image_code:
            return {"code": 401, "data": "验证码已过期"}

        if args["image_code"].lower() != real_image_code.decode().lower():
            return {"code": 400, "data": "验证码输入错误"}

        if not args["username"] or not args["password"]:
            return {"code": 401, "data": "用户名或密码为空"}

        # has_login = redis_store.get('LoginUsername_' + args['username'])
        # if has_login:
        #     return {'code': 400, 'data': "账户已登录"}

        # 解码密码
        try:
            args["password"] = base64.b64decode(args["password"]).decode("utf-8")
        except binascii.Error:
            return {"code": 401, "data": "密码错误"}

        res, userinfo = verify_password(args["username"], args["password"])

        if not res:
            return {"code": 401, "data": userinfo}

        # 角色验证
        if (
            UserRole.query.join(
                Role, and_(UserRole.role_id == Role.id, Role.is_enabled == 1)
            )
            .filter(UserRole.user_id == userinfo["id"])
            .count()
            < 1
        ):
            return {"code": 401, "data": "当前用户未分配角色或归属角色已被禁用"}

        redis_store.setex(
            "LoginUsername_" + args["username"],
            flask_config.EXPIRATION,
            userinfo["id"],
        )
        return {"code": 200, "data": userinfo}


@imageBlueprint.route("/image_code", methods=["GET"], role_control=False)
def get_image_code():
    code_id = request.args.get("code_id")
    name, text, image = captcha.captcha.generate_captcha()
    try:
        redis_store.setex(
            f"ImageCode_{code_id}", flask_config.IMAGE_CODE_REDIS_EXPIRES, text
        )
    except Exception as e:
        current_app.logger.error(e)
        return {"code": 401, "data": "保存图片验证码失败"}

    resp = make_response(image)
    resp.headers["Content-Type"] = "image/jpg"
    return resp


class Logout(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument("username", help="账户名不能为空", required=True)
        args = parser.parse_args()

        try:
            redis_store.delete("LoginUsername_" + args["username"])
        except Exception as e:
            current_app.logger.error(e)
            return {"code": 401, "data": "连接redis异常"}

        return {"code": 200, "data": "退出成功"}
